package jscinttools.utilities.plotterutilities;
import jhplot.HPlotJa;
import jhplot.H1D;
import jhplot.H2D;
import jhplot.P1D;
import jhplot.F1D;
import jhplot.jadraw.JaObject;
import jhplot.jadraw.JaAxes;
import jhplot.jadraw.JaText;
import java.awt.Color;
import jscinttools.utilities.plotterutilities.BeautifierFactory;
import jscinttools.utilities.plotterutilities.PlotFonts;
import jscinttools.utilities.plotterutilities.PlotColors;
import jscinttools.utilities.plotterutilities.FileExtensions;

/**
 *  Standard plotter. Extends HPlotJa plotter and redifined some initial
 *  parameters: All the default fonts are serif and axis labels are centered.
 *
 * @author     Marc-Antoine Verdier
 * @created    1 décembre 2011
 */
public class StdPlotJa extends HPlotJa {

	private TickLabel tickLabelX;
	private TickLabel tickLabelY;
	private PlotLabel labelX;
	private PlotLabel labelY;
	private PlotLabel padTitle;

	private String formatX;
	private String formatY;

	private boolean preliminary;
	private boolean logX;
	private boolean logY;
	private boolean visible;
	private String title;

	private JaAxes axe;
	private PlotterBeautifier pb;
	private Pad pad;
	private JaText prelim;

	/**  Constructor for the StdPlotJa object */
	public StdPlotJa() {
		this("Standard Plotter", false, false, false, false);
	}

	/**
	 *  Constructor for the StdPlotJa object
	 *
	 * @param  title        Title of the plot window (default is "Standard
	 *      Plotter")
	 * @param  visible      Display the plot on the screen (default is false)
	 * @param  preliminary  w a PRELIMINARY label (default is false)
	 */
	public StdPlotJa(String title, boolean visible, boolean preliminary) {
		this(title, visible, preliminary, false, false);
	}

	/**
	 *  Constructor for the StdPlotJa object
	 *
	 * @param  title        Title of the plot window (default is "Standard
	 *      Plotter")
	 * @param  visible      Display the plot on the screen (default is false)
	 * @param  preliminary  Draw a PRELIMINARY label (default is false)
	 * @param  logX         Display X axis in log scale (default is false)
	 * @param  logY         Display Y axis in log scale (default is false)
	 */
	public StdPlotJa(String title, boolean visible, boolean preliminary, boolean logX, boolean logY) {
		super(title, 600, 600, 1, 1, true);
		this.title = title;
		//super.setGTitle(title, PlotFonts.TITLE_FONT);
		//this.gTitle = super.getGTitle();
		this.logX = logX;
		this.logY = logY;
		this.visible = visible;
		this.preliminary = preliminary;
		this.formatX = null;
		this.formatY = null;
		this.prelim = new JaText("PRELIMINARY", 0.02, 0.25, "NDC");
		this.prelim.setFont(PlotFonts.SF_P_25);
		this.prelim.setColor(Color.RED);
		this.prelim.setRotAngle(-45);
		this.axe = super.getPad(1, 1);
		initializePlotter();
		refreshAxes();
	}

	private void initializePlotter() {
		super.setAntiAlias(false);
		//if (super.isContour())
		super.setContourLevels(25); 
		axe.setLocation(0.125, 0.125, "NDC");
		axe.setRelWH(0.75, 0.75, "NDC");
		super.visible(visible);
		super.setLogScale(0, logX);
		super.setLogScale(1, logY);
		super.setTicFont(PlotFonts.TICK_FONT);
		super.setShowStatBox(false);
		super.showKey(false);
		if (preliminary)
			draw(prelim);
		super.update();
	}

	private void refreshAxes() {
		pb = BeautifierFactory.beautifyHPlotJa(this);
		pad = pb.pad(1, 1);
		labelX = pad.axisLabel(0);
		labelY = pad.axisLabel(1);
		tickLabelX = pad.tickLabel(0);
		tickLabelY = pad.tickLabel(1);
		labelX.changeFont(PlotFonts.AXIS_LABEL_FONT);
		labelX.centerLabel(0.0);
		labelY.changeFont(PlotFonts.AXIS_LABEL_FONT);
		labelY.centerLabel(0.015);
		if (logX)
			initLogTickX();
		else
			initLinTickX();
		if (logY)
			initLogTickY();
		else
			initLinTickY();
		super.update();
	}

	private void initLogTickX() {
		tickLabelX.displayAsPowerOfTen();
	}

	private void initLinTickX() {
		tickLabelX.removeNegativeZero();
		if (formatX != null)
			tickLabelX.displayAsDecimal(formatX);
	}

	private void initLogTickY() {
		tickLabelY.displayAsPowerOfTen();
		tickLabelY.axisDistance(-0.01);
	}

	private void initLinTickY() {
		tickLabelY.removeNegativeZero();
		tickLabelY.axisDistance(-0.00);
		if (formatY != null)
			tickLabelY.displayAsDecimal(formatY);
	}

	/**
	 *  Draw an array of H1D
	 *
	 * @param  h1d  The array of H1D to be drawn
	 */
	public void draw(H1D[] h1d) {
		for (int i = 0; i < h1d.length; i++)
			super.draw(h1d[i]);
	}

	/**
	 *  Draw an array of JaObject (like JaKeys or JaText)
	 *
	 * @param  jo  The array of JaObject to be drawn
	 */
	public void draw(JaObject[] jo) {
		for (int i = 0; i < jo.length; i++)
			super.draw(jo[i]);
	}
	
	//public void draw(TextBox box) {
	//	draw(box.getArray());
	//}

	//@Override
	/**  Update the plot */
	public void update() {
		refreshAxes();
	}

	//@Override
	/**
	 *  Sets the Global Title attribute of plot, default Font is Serif, Plain, size
	 *  25
	 *
	 * @param  sname  The new gTitle value
	 */
	public void setGTitle(String sname) {
		super.setGTitle(sname, PlotFonts.TITLE_FONT);
	}

	//@Override
	/**
	 *  Export the plot in 3 formats: png, pdf and eps
	 *
	 * @param  file  the path and name of the output file, extension are
	 *      automatically added
	 */
	public void export(String file) {
		for (int i = 0; i < FileExtensions.FIG_TYPES.length; i++) {
			super.export(file + FileExtensions.FIG_TYPES[i]);
			System.out.println("Writing File : " + file + FileExtensions.FIG_TYPES[i]);
		}
	}

	/**
	 *  Sets the digitsX attribute of the StdPlotJa object
	 *
	 * @param  format  The new digitsX value
	 */
	public void setDigitsX(String format) {
		this.formatX = format;
		refreshAxes();
	}

	/**
	 *  Sets the digitsY attribute of the StdPlotJa object
	 *
	 * @param  format  The new digitsY value
	 */
	public void setDigitsY(String format) {
		this.formatY = format;
		refreshAxes();
	}

	/**
	 *  Gets the visible attribute of the StdPlotJa object
	 *
	 * @return    The visible value
	 */
	public boolean isVisible() {
		return visible;
	}

	/**
	 *  Sets the visible attribute of the StdPlotJa object
	 *
	 * @param  visible  The new visible value
	 */
	public void setVisible(boolean visible) {
		this.visible = visible;
	}

	/**
	 *  Gets the preliminary attribute of the StdPlotJa object
	 *
	 * @return    The preliminary value
	 */
	public boolean isPreliminary() {
		return preliminary;
	}

	/**
	 *  Sets the preliminary attribute of the StdPlotJa object
	 *
	 * @param  preliminary  The new preliminary value
	 */
	public void setPreliminary(boolean preliminary) {
		this.preliminary = preliminary;
	}

	/**
	 *  Gets the logX attribute of the StdPlotJa object
	 *
	 * @return    The logX value
	 */
	public boolean isLogX() {
		return logX;
	}

	/**
	 *  Sets the logX attribute of the StdPlotJa object
	 *
	 * @param  logX  The new logX value
	 */
	public void setLogX(boolean logX) {
		this.logX = logX;
	}

	/**
	 *  Gets the logY attribute of the StdPlotJa object
	 *
	 * @return    The logY value
	 */
	public boolean isLogY() {
		return logY;
	}

	/**
	 *  Sets the logY attribute of the StdPlotJa object
	 *
	 * @param  logY  The new logY value
	 */
	public void setLogY(boolean logY) {
		this.logY = logY;
	}
}

